/**
 * Benchmark utilities
 */
import { performance } from 'perf_hooks';

/**
 * Formats a number to a human-readable string with the given unit
 * @param num - The number to format
 * @param unit - The unit to append (default: '')
 * @returns Formatted string
 */
export function formatNumber(num: number, unit: string = ''): string {
  const formatted = num.toLocaleString('en-US', {
    minimumFractionDigits: 0,
    maximumFractionDigits: 2
  });
  return `${formatted}${unit ? ' ' + unit : ''}`;
}

/**
 * Times the execution of a function
 * @param fn - The function to time
 * @returns Tuple of [result, elapsedMs]
 */
export async function timeExecution<T>(fn: () => Promise<T> | T): Promise<[T, number]> {
  const start = performance.now();
  const result = await fn();
  const end = performance.now();
  return [result, end - start];
}

/**
 * Creates a delay promise
 * @param ms - Milliseconds to delay
 * @returns Promise that resolves after the delay
 */
export function delay(ms: number): Promise<void> {
  return new Promise(resolve => setTimeout(resolve, ms));
}

/**
 * Generates an array of numbers in the given range
 * @param start - Start of the range (inclusive)
 * @param end - End of the range (inclusive)
 * @returns Array of numbers
 */
export function range(start: number, end: number): number[] {
  return Array.from({ length: end - start + 1 }, (_, i) => start + i);
}

/**
 * Runs a function concurrently n times
 * @param n - Number of times to run the function
 * @param fn - Function to run
 * @returns Array of results
 */
export async function runConcurrently<T>(
  n: number, 
  fn: (index: number) => Promise<T>
): Promise<T[]> {
  return Promise.all(range(0, n - 1).map(fn));
} 